/* EMU 1.1
 * 2012 Rogerio Drummond
 * IC – Unicamp
*/

package abstractions;
import interfaces.EMUW;

import java.util.LinkedList;

// Manages the EMU Document abstraction: a list of atoms that represents the document.
public class EMUDoc {
	// info about the EMUDoc file
	public String fileName;
	public String pathName;
	public boolean isRemote;

	// where it is shown and who edits it
	public LinkedList<EMUW> winList;			// where this EMUDoc is shown
	public LinkedList<Integer> userList;		// users editing this EMUDoc

	// EMU implementation of the EMUDoc
	LinkedList<Atom> al = new LinkedList<Atom>();	// lista dos atomos do documento
	Pos cp;					// current position
	Selection cs;			// current selection
	Part cb;				// clipboard
	public History h;		// execution history (histU, histC, undo and redo)

	// state info
	public boolean isDirty;
	
	// ********************** CONSTRUCTORS

	// Cria um documento vazio
	public EMUDoc() {}

	public EMUDoc(String pathName, boolean isRemote) {}

	// Cria um documento a partir de um arquivo de texto
	public EMUDoc(String texto) {}

	// Cria um documento a partir de um arquivo de texto e historia de modificacoes
	public EMUDoc(String texto, History h) {}


	// ********************** Auxiliary methods

	
	// ********************** Window manager

	// add a new Window to the list of Windows for this EMUDoc
	void addWin(EMUW win) {
		winList.add(win);
	}

	// 
	public void setText(String text) {		
		// parse the text, setup each Atom and insert them into the al.
		
		cp = new Pos(al.get(0), 0);
	}


	// ********************** Document manager

	public void openDoc() {
	}
	
	public void closeDoc() {
		if (isRemote) {
			// sends all recent comands to the Server
		
		} else 
			if (isDirty) {
				@SuppressWarnings("unused")
				String texto = this.toString();
			
				// salva arquivo
			
		}
		// close (removes this from the doc and win lists
		
	}

	// returns the text of the document
	public String toString() {
		StringBuilder s = new StringBuilder();
		for (Atom a: al)
			s.append(a.at);
		return s.toString();
	}
	
	
	// ********************** Metods indirectly called by the Server
	
	// Locks the atomId to userId
	void lockAtom(int serverId, int docId, AtomId aId, int userId) {}

	// Unlocks the atomId
	void unlockAtom(int serverId, int docId, AtomId aId) {}

	// Add an user to the userList
	void addClientToDoc(int serverId, int docId, int userId) {}

	// Remove an user from the userList
	void removeClientFromDoc(int serverId, int docId, int userId) {}


	
	// ********************** Editing the EMUDoc

	// This methods are called in response to user actions on the editing window which
	// can be of 2 forms: menu commands (cut, copy, paste, select all, ...) and
	// direct editing actions on the text window (events captured at that window).

	// Retorna o Atom posterior a a na atomList
	Atom next(Atom a) {
		return null;		// to compile ...
	}

	// Retorna o Atom anterior a ana AtomList
	Atom prev(Atom a) {
		return null;		// to compile ...
	}
	
	// Insere uma part a partir de pos
	void insertP(Part p, Pos pos) {}

	// Insere o ClipBoard do usuario, Part pode ser composta pelo conteudo de varios
	// Atom e no comeco e no fim por pedacos de conteudo de Atom.
	void setClipBoard(Part p) {}

	// Remove n caracteres a frente se n>0, remove -n caracteres atras se n<0
	void del(Pos pos, int n) {}

	// guarda selecao no clipboard
	public void copy() {}

	// Seleciona um intervalo (co,cc) a (ca1,cc1). Apos o uso (ca1,cc1).
	void setSelection(Pos l) {}

	// Remove a selecao e guarda no clipboard
	public void cut() {}

	// insere conteudo do clipboard na posicao do cursor
	public void paste() {}

	// Cria um Atom e insere o antes do Atom dado.
	Atom newAtomBefore(AtomId aid) {
		return null;		// to compile ...
	}

	// Cria um Atom e insere depois do Atom dado.
	Atom newAtomAfter(AtomId aid) {
		return null;		// to compile ...
	}

	// remove do EMUDoc o Atom passado
	void delAtom(AtomId aid) {}

	// divide o Atom a em dois Atoms (a, b) na posicao p.
	// Retorna o Atom b
	Atom splitAtom(AtomId aid, Pos p) {
		return null;		// to compile ...
	}

	// Une dois Atom em um novo Atom que retem a AtomId de a.}
	void joinAtom(AtomId aid, AtomId b) {}

	// Creates a copy of the
	Part copy(Selection sel) {
		return null;		// to compile ...
	}

	// Remove a Part correspondente a curSelection e NAO armazena no clipBoard.
	void del(Selection sel) {}

	// Remove a Part correspondente a curSelection e armazena no clipBoard.
	void cut(Selection sel) {}

	// Insere na curPos a Part p.
	void paste(Part p) {}

	// set the current selection.
	void setSelection(Pos p1, Pos p2) {}

	//
	public void selectAll() {
		// Effects: 
		// Pre: 
		// Mod: 
		setSelection(new Pos(al.getFirst(), 0), new Pos(al.getLast(), al.getLast().at.length()));
	}
}

